Copy files


How can I copy files in Delphi ?

If you want to make a typical copy of a file; simply you can use CopyFile API function,
but if you want to encrypt a file while copying or add a header to the file or any
other modification; you have to copy files manually by using
untyped file.

Copy files using CopyFile:

- Drop two Edit boxes and a Button.
- At Button's OnClick event write:


CopyFile(PChar(Edit1.Text),
  PChar(Edit2.Text), false);

After running, enter a source file name in Edit1, and a destination file name in
Edit2 then press the button.

As you might know, API functions always deal with null-terminated strings, so that
you have to typecast any string to a
PChar. PChar represents null-terminated string
in Delphi and Pascal.

If last parameter is
False; copy will not care about destination file existance,
it will overwrite destination file if it is exists. If this parameter is
Ture; the
copy function will fail if destination file is exists.

Copy file returns
True if success and False if failed.



Copy files using untyped file

As I've said you can copy files manually using untyped file in cases you need to
perform some modification to files such as: encryption, compression, add header to
a file, and file transfer.
Reading and writing from and to untyped files done by
BlockRead and BlockWrite procedures
(For more information about untyped file see
Programming with Turbo Pascal 7 Electronic
book).


- Drop two Edit boxes and a Button.
- Write this procedure:

function FCopy(SourceName, TargetName: string): boolean;
var
SourceF, TargetF: file;
Buf: array [0 .. 1023] of byte;
NumRead: integer;
begin
Result:= false;
try
  AssignFile(SourceF, SourceName);
  AssignFile(TargetF, TargetName);
  FileMode:= 0;  // Read only
  Reset(SourceF, 1);  // Record size = 1 byte
  Rewrite(TargetF, 1); // Create target file (destination)

   { You can write header here, such as: }
  { MyHeader:= 6 // MyHeader is an integer }
  { BlockWrite(TargetF, MyHeader, SizeOf(MyHeader)); }

  (*** Coping ***)
  while not Eof(SourceF) do
  begin
    BlockRead(SourceF, Buf, SizeOf(Buf), NumRead);
     { You can perform any modification to Buf here such as: }
    { Encrypt(Buf, NumRead); // Suppose that Encrypt is a procedure }
     BlockWrite(TargetF, Buf, NumRead);
  end; // while not Eof..
  CloseFile(SourceF);
  CloseFile(TargetF);
  Result:= True;

except
  on E: EInOutError do
  begin
    MessageDlg(E.Message, mtError, [mbOk], 0);
    exit;
  end; // on E:..
end; // try
end;



- At Button's OnClick event write:

 if FCopy(Edit1.Text, Edit2.Text) then
  MessageDlg('File copied successfully', mtInformation, [mbOk], 0)
else
  MessageDlg('Error while coping file', mtError, [mbOk], 0);


Run this program and test it. FCopy procedure works properly, isn't it ? The answer
is NO, some thing is missing, there is a big difference between source and target
file, didn't you observe it ? If you did not, try to check it now and see both files
information. Look at files date! Source and target files date are different, we forget
to copy it. When we create a file current date and time will be set to new file as
an updated time, so how can we copy file date and time ?

The answer is very simple, by using
FileAge and FileSetDate functions. FileAge returns
file date and time, we can use it to get source file date and time.
FileSetDate sets
file date and time, so that we can use it to set target file date and time. FCopy
function will be: ( Additions written in
Red color )

function FCopy(SourceName, TargetName: string): boolean;
var
SourceF, TargetF: file;
Buf: array [0 .. 1023] of byte;
NumRead: integer;
 Age, Handle: integer;
begin
Result:= false;
try
  AssignFile(SourceF, SourceName);
  AssignFile(TargetF, TargetName);
  FileMode:= 0;  // Read only
  Reset(SourceF, 1);  // Record size = 1 byte
  Rewrite(TargetF, 1); // Create target file (destination)

  { You can write header here, such as: }
  { MyHeader:= 6 // MyHeader is an integer }
  { BlockWrite(TargetF, MyHeader, SizeOf(MyHeader)); }

  (*** Coping ***)
  while not Eof(SourceF) do
  begin
    BlockRead(SourceF, Buf, SizeOf(Buf), NumRead);
    { You can perform any modification to Buf here such as: }
    { Encrypt(Buf, NumRead); // Suppose that Encrypt is a procedure }
    BlockWrite(TargetF, Buf, NumRead);
  end; // while not Eof..
  CloseFile(SourceF);
  CloseFile(TargetF);

   (*** Copy file date and time ***)
  Age:= FileAge(SourceName);
  Handle:= FileOpen(TargetName, fmOpenWrite);
  FileSetDate(Handle, Age);
  FileClose(Handle);
   Result:= True;

except
  on E: EInOutError do
  begin
    MessageDlg(E.Message, mtError, [mbOk], 0);
    exit;
  end; // on E:..
end; // try
end;

See also

Untyped files